/*
    DIMVisual-KAAPI, the DIMVisual bundle for KAAPI trace files
    Copyright (c) 2008 Lucas Mello Schnorr <schnorr@gmail.com>

    This file is part of DIMVisual-KAAPI.

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#include "KAAPIConverter.h"
#include <kaapi>

@implementation KAAPIConverter (KProcessor)
- (id) convertKProcessorWithEvent: (GEvent *) event
{
	NSMutableArray *ret = [NSMutableArray new];
	
	GFields *f = [event fields];

	gid = [[f fieldWithSimpleStringKey:@"gid"] description];
	cid = [[f fieldWithSimpleStringKey:@"cid"] description];
	time = [[event timestamp] description];
	levelid = [[f fieldWithSimpleStringKey:@"level"] description];
	eventid = [[f fieldWithSimpleStringKey:@"event"] description];
	hostname = [[f fieldWithSimpleStringKey:@"hostname"] description];
	[mappingGidHostname setObject: hostname forKey: gid];
	[mappingGidHostname setObject: gid forKey: hostname];

	int ilevelid, ieventid;
	ilevelid = atoi([levelid cString]);
	ieventid = atoi([eventid cString]);
	
	NSString *site;
	NSString *cluster;
	NSString *machine;
	NSString *process;

	NSArray *aux = [hostname componentsSeparatedByString: @"-"];
	NSString *straux = [aux objectAtIndex: 0];

	if ([grid5000 objectForKey: straux] != nil) { //grid5000
		site = [grid5000 objectForKey: straux];
		cluster = straux;

		NSString *rest = [aux objectAtIndex: 1];
		NSArray *aux2;
		aux2 = [rest componentsSeparatedByString: @"."];

		machine = [aux2 objectAtIndex: 0];
	}else{
		site = cluster = machine = hostname;
	}
	process = gid;

	NSArray *creation = [provider createContainerForEntity:
		[NSArray arrayWithObjects:
			@"site", @"cluster", @"machine",
			@"process", @"k-processor", nil]
		ids:
		[NSArray arrayWithObjects:
			site, cluster, machine, process, cid, nil]
		time: time];
	container = [provider identifierForEntity:
		[NSArray arrayWithObjects:
			@"site", @"cluster", @"machine",
			@"process", @"k-processor", nil]
		ids:
		[NSArray arrayWithObjects:
			site, cluster, machine, process, cid, nil]];
	if ([creation count] != 0){
		[ret addObjectsFromArray: creation];
	}

	//translate events
	switch (ilevelid){
		case Event::TR_UTIL_LEVEL:
			switch (ieventid){
				case Event::UTIL_THREAD_RUN:
					[ret addObject:
					[self addPajeSetState: @"RUN"
						toState: @"State7"
						time: time
						container: container]];
					break;
				case Event::UTIL_THREAD_START:
				case Event::UTIL_THREAD_TERM:
				default:
					break;
			}
			break;
		case Event::TR_KERNEL_LEVEL:
			switch (ieventid){
				case Event::CORE_PROCESSOR_IDLE0:
					[ret addObject:
					[self addPajeSetState: @"IDLE"
						toState: @"State7"
						time: time
						container: container]];
					break;
				case Event::CORE_PROCESSOR_IDLE1:
					[ret addObject:
					[self addPajeSetState: @"RUN"
						toState: @"State7"
						time: time
						container: container]];
					break;
				case Event::CORE_THREAD_RSTEAL:
					[ret addObject:
					[self addPajePushState:@"RSTEAL"
						toState: @"State7"
						time: time
						container: container]];

					/* generating arrow to gidvictim */
					static long long nkey = 0;
					NSString *supercontainer, *key;
					NSString *stealercontainer;
					NSString *victimcontainer;
					supercontainer = [provider 
						identifierForEntity:
						[NSArray arrayWithObjects:
							@"0", nil]
						ids:
						[NSArray arrayWithObjects:
							@"0", nil]];
					stealercontainer = container;

					key = [NSString stringWithFormat:
						@"s%d", nkey++];
					PajeStartLink *sl;
					sl = [[PajeStartLink alloc] init];
					[sl setTime: time];
				       [sl setSourceContainer:stealercontainer];
					[sl setContainer: supercontainer];
					[sl setEntityType: 
					     [provider aliasToName:@"steal"]];
					[sl setValue: 
					     [provider aliasToName:@"steal"]];
					[sl setKey: key];
					[ret addObject: sl];
					[sl release];

					NSString *gidvictim;
					gidvictim = [[f 
					  fieldWithSimpleStringKey:@"gidvictim"]
					       description];
					[ret addObjectsFromArray:
						[provider
						createContainerForEntity:
						[NSArray arrayWithObjects:
							@"site", @"cluster",
							@"machine", @"process",
							@"k-processor",
							nil]
						ids:
						[NSArray arrayWithObjects:
							site, cluster,
							machine,gidvictim,@"4",
							nil]
						time: time]];
					
					victimcontainer = [provider
						identifierForEntity:
						[NSArray arrayWithObjects:
							@"site", @"cluster",
							@"machine", @"process",
							@"k-processor",
							nil]
						ids:
						[NSArray arrayWithObjects:
							site, cluster,
							machine,gidvictim,
							@"4",nil]];

					PajeEndLink *el;
					el = [[PajeEndLink alloc] init];
					[el setTime: time];
					[el setContainer: supercontainer];
					[el setDestContainer: victimcontainer];
					[el setEntityType:
					     [provider aliasToName:@"steal"]];
					[el setValue: 
					     [provider aliasToName:@"steal"]];
					[el setKey: key];
					[ret addObject: el];
					[el release];
	
					break;
				case Event::CORE_THREAD_RETRSTEAL:
					[ret addObject:
					[self addPajePopState: @"State7"
						time: time
						container: container]];
					break;
			}
			break;
	}
	[ret autorelease];
	return ret;
}
@end
